library DivineShieldBuff initializer Init requires entities, utils

    globals
        public integer RAW_CODE = 'AB00'
        public integer BUFF_ID = 'BHds'
    endglobals

    /**
    * 神圣护甲
    */
    struct DivineShieldBuff extends array

        delegate Buff m_buff

        method setDuration takes real duration returns nothing
            set this.m_duration = duration
        endmethod

        method setEffectPath takes string effectPath, string attachName returns nothing
            set this.m_effectAPath = effectPath
            set this.m_effectAAttachName = attachName
        endmethod

        method showEffect takes nothing returns nothing
            set this.m_effectA = AddSpecialEffectTarget(this.m_effectAPath, this.m_unit, this.m_effectAAttachName)
        endmethod

        static method create takes nothing returns thistype
            local thistype this = thistype(Buff.create(BUFF_ID))
            set this.m_buff = Buff(this)
            set this.m_buffKind = BUFF_POSITIVE

            call this.setEffectPath("Abilities\\Spells\\Human\\DivineShield\\DivineShieldTarget.mdl", "origin")

            return this
        endmethod

    endstruct


    private function OnExpire takes nothing returns nothing
        local Buff buf = GetTimerData(GetExpiredTimer())
        local Unit ud = Unit.get(buf.m_unit)

        call ud.removeBuff(buf)
        call UnitUtils.disableUnitMagicImmunity(ud.m_unit)

        call buf.destroy()
    endfunction

    private function OnStack takes integer dt returns nothing
        local Buff buf = Buff(dt)

        if buf.m_buffId == BUFF_ID then
            call TimerStart(buf.getTimer(), buf.m_duration, false, function OnExpire)
        endif
    endfunction

    private function OnApply takes integer dt returns nothing
        local DivineShieldBuff buf = DivineShieldBuff(dt)

        if buf.m_buffId == BUFF_ID then
            call buf.showEffect()
            call UnitUtils.enableUnitMagicImmunity(buf.m_unit)
        endif
    endfunction

    private function OnActive takes integer dt returns nothing
        local Buff buf = Buff(dt)

        if buf.m_buffId == BUFF_ID then
            set buf.m_rawCode = RAW_CODE

            call TimerStart(buf.getTimer(), buf.m_duration, false, function OnExpire)
        endif
    endfunction

    private function OnDamageModifier takes nothing returns nothing
        local Unit dud = Unit.get(Damage.target)
        local Buff buf = dud.getBuffById(BUFF_ID)
        if buf > 0 then
            set Damage.amount = 0
            call AddEffectTarget("Abilities\\Spells\\Human\\Defend\\DefendCaster.mdl", buf.m_unit, "origin")
        endif
    endfunction

    private function Init takes nothing returns nothing
        call RegisterBuffActiveResponse(OnActive)
        call RegisterBuffApplyResponse(OnApply)
        call RegisterBuffStackResponse(OnStack)
        
        call Damage.registerModifier(function OnDamageModifier)
    endfunction

endlibrary
